package org.hit.burkun.utils;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.hit.burkun.db.DBHelper;
import org.hit.burkun.file.FileHelper;
import org.hit.burkun.model.Content;
import org.hit.burkun.model.FenciContent;
import org.hit.burkun.model.UserProfile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class StaticMethods {

	private static Logger log = LoggerFactory.getLogger(StaticMethods.class);

	private static DBHelper dbh = DBHelper.getServerDataDBHelper();
	private static Map<String, Content> mid2contentTrain = new HashMap<>();
	private static Map<String, Content> mid2contentPredict = new HashMap<>();
	private static Map<String, String[]> mid2ThreeNumber = new HashMap<>();
	private static Map<String, Collection<String>> trainUid2Mid = new HashMap<>();
	private static Map<String, Collection<String>> predictUid2Mid = new HashMap<>();

	private static void initTrain(){
		if(mid2contentTrain.size() == 0){
			log.debug("get mid and conent from sina_train...");
			//load mid2content
			dbh.connectionDB();
			Collection<String[]> res = dbh.queryData("select mid, content from sina_train", 2);
			dbh.disconnection();
			for(String[] line : res){
				Content c = new Content(line[0], line[1]);
				mid2contentTrain.put(line[0], c);
			}
		}
	}

	private static void initPredict(){
		if(mid2contentPredict.size() == 0){
			log.debug("get mid and conent from sina_predict...");
			//load mid2content
			dbh.connectionDB();
			Collection<String[]> res = dbh.queryData("select mid, content from sina_predict", 2);
			dbh.disconnection();
			for(String[] line : res){
				Content c = new Content(line[0], line[1]);
				mid2contentPredict.put(line[0], c);
			}
		}
	}

	private static Map<String, FenciContent> fenciContent = new HashMap<>();

	private static void initFenciContent(){
		if(fenciContent.size() == 0){
			log.debug("get fencicontent mid_fenci...");
			//load mid2content
			dbh.connectionDB();
			Collection<String[]> res = dbh.queryData("select mid, fenci,at_someone,topics,other_topics from mid_fenci", 5);
			dbh.disconnection();
			for(String[] line : res){
				FenciContent fc = new FenciContent(line[0], line[1], line[2], line[3],line[4]);
				fenciContent.put(line[0], fc);
			}
		}
	}
	private static void initMidThreeNumber(){
		if(mid2ThreeNumber.size() == 0){
			log.debug("get mid, repost, `comment` , likes from sina_train...");
			//load mid2content
			dbh.connectionDB();
			Collection<String[]> res = dbh.queryData("select mid, repost, `comment` , likes from sina_train as a,  predict_in_train as b where a.uid = b.uid", 4);
			dbh.disconnection();
			for(String[] line : res){
				mid2ThreeNumber.put(line[0], line);
			}
			log.debug("get mid, repost, `comment` , likes from sina_train done...");
		}
	}

	private static void initTrainUid2Mids(){
		if(trainUid2Mid.size() == 0){
			log.debug("get uid, mids from sina_train...");
			//load mid2content
			dbh.connectionDB();
			Collection<String[]> res = dbh.queryData("SELECT a.uid, a.mid FROM sina_train as a, predict_in_train as b where a.uid  = b.uid", 2);
			dbh.disconnection();
			for(String[] line : res){
				if(trainUid2Mid.containsKey(line[0])){
					trainUid2Mid.get(line[0]).add(line[1]);
				}else{
					Collection<String> set = new HashSet<>();
					set.add(line[1]);
					trainUid2Mid.put(line[0], set);
				}
			}
			log.debug("get uid, mids from sina_train done...");
		}
	}

	private static void initPredictUid2Mids(){
		if(predictUid2Mid.size() == 0){
			log.debug("get uid, mids from sina_predict...");
			//load mid2content
			dbh.connectionDB();
			Collection<String[]> res = dbh.queryData("SELECT uid, mid FROM sina_predict", 2);
			dbh.disconnection();
			for(String[] line : res){
				if(predictUid2Mid.containsKey(line[0])){
					predictUid2Mid.get(line[0]).add(line[1]);
				}else{
					Collection<String> set = new HashSet<>();
					set.add(line[1]);
					predictUid2Mid.put(line[0], set);
				}
			}
			log.debug("get mid, likes, repost, `comment` from sina_predict done...");
		}
	}

	public static Map<String, Content> getMid2ContentTrain(){
		initTrain();
		return mid2contentTrain;
	}

	public static Map<String, Content> getMid2ContentPredict(){
		initPredict();
		return mid2contentPredict;
	}

	public static Map<String, String[]> getMidThreeNumber(){
		initMidThreeNumber();
		return mid2ThreeNumber;
	}



	public static Collection<String> getUids(String tbName){
		log.debug("get uids from " + tbName);
		DBHelper dbh = DBHelper.getServerDataDBHelper();
		dbh.connectionDB();
		Collection<String> res= dbh.queryData("select distinct uid from "+ tbName);
		dbh.disconnection();
		log.debug("get uids from " + tbName + " done!");
		return res;
	}

	public static UserProfile getUserProfile(String uid){
		log.debug("get uids profile...");
		DBHelper dbh = DBHelper.getServerDataDBHelper();
		dbh.connectionDB();
		Collection<String[]> res= dbh.queryData("select uid, like_sum, comment_sum, repost_sum, weibo_num, days from sina_user_profile where uid = '" + uid + "'", 6);
		dbh.disconnection();
		log.debug("get uids profile done!");
		UserProfile up = new UserProfile();
		for(String[] line : res){
			up.uid = line[0];
			up.likeSum = Integer.parseInt(line[1]);
			up.commentSum = Integer.parseInt(line[2]);
			up.repostSum = Integer.parseInt(line[3]);
			up.weiboNum = Integer.parseInt(line[4]);
			up.days = Integer.parseInt(line[5]);
			return up;
		}
		return null;
	}

	public static Collection<String> getUserTrainMid(String uid){
		log.debug("get uids mids...");
		initTrainUid2Mids();
		if(trainUid2Mid.containsKey(uid)){
			return trainUid2Mid.get(uid);
		}
		log.debug("get uids mids done!");
		return null;
	}

	public static Collection<String> getUserPredictMid(String uid){
		log.debug("get uids mids...");
		initPredictUid2Mids();
		if(predictUid2Mid.containsKey(uid)){
			return predictUid2Mid.get(uid);
		}
		log.debug("get uids mids done!");
		return null;
	}



	/**
	 * format result uid, mid, 转发，评论， 赞
	 */
	public static void writeFile(Collection<String[]> res, boolean isAppend){
		String dataName = "version.txt";
		Collection<String> finalRes = new LinkedList<>();
		for(String[] line : res){
			String[] dd = new String[3];
			dd[0] = line[0];
			dd[1] = line[1];
			dd[2] = line[2] + "," + line[3] + "," + line[4];
			finalRes.add(StringUtils.join(dd, "\t"));
		}
		log.debug("write file... " + dataName);
		FileHelper.writeFile(dataName, finalRes, isAppend);
	}

	public static void writeFile(Collection<String[]> res){
		writeFile(res, true);
	}

	public static FenciContent getMidFenciContent(String mid){
		initFenciContent();
		if(fenciContent.containsKey(mid)){
			return fenciContent.get(mid);
		}
		return null;
	}

	// ----------------------------------------------------------------------
	// New add method by mingchen
	/**
	 * Get the Map of fenci Content
	 * 
	 * @return Map<String,FenciContent> 2015年8月15日
	 */
	public static Map<String, FenciContent> getFenciContent() {
		if (fenciContent == null || fenciContent.size() == 0) {
			initFenciContent();
			log.info("Loading fenciContent Map");
		}

		return fenciContent;
	}

	/**
	 * Get the distinct users in train
	 * 
	 * @return Set<String> 2015年8月15日
	 */
	public static Set<String> getTrainUids() {
		if (trainUid2Mid == null || trainUid2Mid.size() == 0) {
			initTrainUid2Mids();
			log.info("Loading trainUids2Mids");
		}
		return trainUid2Mid.keySet();
	}

	/**
	 * Get all distinct mids from train
	 * 
	 * @return Set<String> 2015年8月15日
	 */
	public static Set<String> getTrainMids() {
		Set<String> set = new HashSet<String>();
		for (String uid : getTrainUids()) {
			set.addAll(trainUid2Mid.get(uid));
		}
		return set;
	}

	/**
	 * Get all the distinct uid from predict
	 * 
	 * @return Set<String> 2015年8月15日
	 */
	public static Set<String> getPredictUids() {
		if (predictUid2Mid == null || predictUid2Mid.size() == 0) {
			initPredictUid2Mids();
		}
		return predictUid2Mid.keySet();
	}

	/**
	 * Get all the distinct mids from predict
	 * 
	 * @return Set<String> 2015年8月15日
	 */
	public static Set<String> getPredictMids(){
		Set<String> set  = new HashSet<String>();
		for(String uid:getPredictUids()){
			set.addAll(predictUid2Mid.get(uid));
		}
		return set;
	}
	// --------------------------------------------------------------------

}
